package com.kx.yooli.kx.wechat.service.index.impl;

import com.google.common.collect.Maps;
import com.kx.yooli.kx.wechat.entity.bill.BillEntity;
import com.kx.yooli.kx.wechat.entity.nplm.*;
import com.kx.yooli.kx.wechat.entity.repayment.ActiveRepayOperate;
import com.kx.yooli.kx.wechat.entity.repayment.RepaymentEntity;
import com.kx.yooli.kx.wechat.entity.repayment.RepaymentMergeActive;
import com.kx.yooli.kx.wechat.mapper.bill.BillMapper;
import com.kx.yooli.kx.wechat.mapper.credit.ICreditMapper;
import com.kx.yooli.kx.wechat.mapper.nplm.*;
import com.kx.yooli.kx.wechat.mapper.repayment.IRepaymentMapper;
import com.kx.yooli.kx.wechat.mapper.user.UserInfoMapper;
import com.kx.yooli.kx.wechat.mapper.user.UserInfoSsoMapper;
import com.kx.yooli.kx.wechat.po.result.AjaxResult;
import com.kx.yooli.kx.wechat.po.user.NplmBaseCustInfo;
import com.kx.yooli.kx.wechat.po.user.UserInfo;
import com.kx.yooli.kx.wechat.po.user.UserInfoSso;
import com.kx.yooli.kx.wechat.service.index.IndexService;
import jakarta.annotation.Resource;
import org.apache.commons.compress.utils.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class IndexServiceImpl implements IndexService {
    private final ICreditMapper iCreditMapper;
    private final UserInfoMapper infoMapper;
    private final BillMapper billMapper;

    private final IRepaymentMapper iRepaymentMapper;
    private final ILoanContractMapper iLoanContractMapper;

    @Resource
    private UserInfoSsoMapper userInfoSsoMapper;
    @Resource
    private NplmLoanContractMapper nplmLoanContractMapper;

    @Resource
    private NplmOverdueCaseMapper nplmOverdueCaseMapper;
    @Resource
    private NplmRepayPlanMapper nplmRepayPlanMapper;
    private final Logger log = LoggerFactory.getLogger(IndexServiceImpl.class);

    public IndexServiceImpl(ICreditMapper iCreditMapper, UserInfoMapper infoMapper, BillMapper billMapper, IRepaymentMapper iRepaymentMapper, ILoanContractMapper iLoanContractMapper) {
        this.iCreditMapper = iCreditMapper;
        this.infoMapper = infoMapper;
        this.billMapper = billMapper;
        this.iRepaymentMapper = iRepaymentMapper;
        this.iLoanContractMapper = iLoanContractMapper;
    }
    @Resource
    private CustInfoMapper cus;

    @Override
    public Integer selectBill(String mobile) {
        Integer i = 0;
        //first select userinfo table get certNo
        UserInfo userInfo = infoMapper.selectCertNoByMobile(mobile);
        if(null != userInfo){
            if(null !=userInfo.getCertNo() && !userInfo.getCertNo().isBlank()) {
                //use not blank certNo select repayment loanNo
                BillEntity billEntity = billMapper.selectLoanByCertNo(userInfo.getCertNo());
                if (null != billEntity) {
                    if(!billEntity.getLoanNo().isBlank()){
                        //use not blank loanNo select bill info and return
                       return iLoanContractMapper.selectCountByLoanNo(billEntity.getLoanNo());
                    }
                }
            }
        }
        return i;
    }


    @Override
    public Integer selectCredit(String mobile) {
        Integer i = 0;
        UserInfo userInfo = infoMapper.selectCertNoByMobile(mobile);
        if(null != userInfo){
            if(null != userInfo.getCertNo() && !userInfo.getCertNo().isBlank()) {
              i  = iCreditMapper.selectCountByCertNo(userInfo.getCertNo());
            }
        }
        return i;
    }

    @Override
    public Integer selectBinding(String mobile) {
        Integer i = 0;
        UserInfo userInfo = infoMapper.selectCertNoByMobile(mobile);
        if(null != userInfo){
            if(null != userInfo.getCertNo() && !userInfo.getCertNo().isBlank()) {
                i  = iCreditMapper.selectCountByCertNo(userInfo.getCertNo());
            }
        }
        return i;
    }

    @Override
    public Integer selectUser(String mobile) {
        Integer i = 0;
        Integer user = infoMapper.selectCountByMobile(mobile);
        if(user>0){
            return user;
        }
       return  i;
    }

    @Override
    public Integer selectRepayment(String mobile) {
        Integer i = 0;
        UserInfo userInfo = infoMapper.selectCertNoByMobile(mobile);
        if(null != userInfo) {
            if (null != userInfo.getCertNo() && !userInfo.getCertNo().isBlank()) {
                //iRepaymentMapper.selectListLoanByCertNo(userInfo.getCertNo()).size();
                return iRepaymentMapper.selectCountByCertNo(userInfo.getCertNo());
            }
        }
        return i;
    }
    @Override
    public List<RepaymentMergeActive> selectByListRepayment(String mobile){
        //UserInfo userInfo = infoMapper.selectCertNoByMobile(mobile);
        //List<UserInfoSso> userInfoSso = userInfoSsoMapper.selectIsExistCertNo(mobile);
        //mobile = "15081461401";
        List<RepaymentMergeActive> resultList = Lists.newArrayList();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        /*
        new logic first select NPLM database if result is null or empty select wechat service database
        if it's not null in two by one  put in resultList and return it;
        */
        if(mobile.isBlank()){
            return null;
        }
        String certNo =  "";
        List<Map> strings = nplmLoanContractMapper.selectLoanNobyMobile(mobile);
        List<NplmOvrdueCase> nplmOvrdueCases = null;
        if(strings.isEmpty()){
            List<UserInfoSso> userInfoSso = userInfoSsoMapper.selectIsExistCertNo(mobile);
            certNo = userInfoSso.getFirst().getCertNo();
            if(null != certNo ) {
                List<String> strings1 = nplmLoanContractMapper.selectLoanNoByIdCard(certNo.isBlank()?"":certNo);
                if(!strings1.isEmpty()) {
                    nplmOvrdueCases = nplmOverdueCaseMapper.selectByIdCard(strings1);
                }
            }
            else{
                UserInfo userInfo = infoMapper.selectCertNoByMobile(mobile);
                if(null != userInfo ) {
                    List<String> strings1 = nplmLoanContractMapper.selectLoanNoByIdCard(userInfo.getCertNo().isBlank()?"":userInfo.getCertNo());
                    if (!strings1.isEmpty()) {
                        nplmOvrdueCases = nplmOverdueCaseMapper.selectByIdCard(strings1);
                    }
                }
            }

        }
        else{
            /*if(strings.size()>1){
                 certNo = String.valueOf(strings.getFirst().get("CERT_NO"));
                nplmOvrdueCases  = nplmOverdueCaseMapper.selectByIdCard(strings);
            }else {
                loanNO = String.valueOf(strings.getFirst().get("LOAN_NO"));
                nplmOvrdueCases  = nplmOverdueCaseMapper.selectByLoanNo(loanNO);
            }*/
            List<String> list = Lists.newArrayList();
            for (Map mp :strings){
                list.add(mp.get("LOAN_NO").toString());
            }
            if(!list.isEmpty()){
                nplmOvrdueCases  = nplmOverdueCaseMapper.selectByLoanNo(list);
            }
        }
        if(null != nplmOvrdueCases){
            for (NplmOvrdueCase nplmOvrdueCase : nplmOvrdueCases) {
                RepaymentMergeActive repaymentMergeActive = new RepaymentMergeActive();
                repaymentMergeActive.setCertNo(nplmOvrdueCase.getCertNo());
                repaymentMergeActive.setLoanNo(nplmOvrdueCase.getLoanNo());
                NplmLoanContract contract = nplmLoanContractMapper.selectLoanNoObjectByCertNo(nplmOvrdueCase.getLoanNo());
                repaymentMergeActive.setLoanAmount(contract.getLoanAmount());
                repaymentMergeActive.setStatus(contract.getContractStatus());
                if (null != nplmOvrdueCase.getRepayTime()){
                    repaymentMergeActive.setClearTime(sdf.format(nplmOvrdueCase.getRepayTime()));
                }
                resultList.add(repaymentMergeActive);
            }

        }
        return resultList;
    }

    @Override
    public List<RepaymentMergeActive> selectByListInfoRepayment(String loan) {
        List<RepaymentMergeActive> resultList = Lists.newArrayList();
        if(loan.isEmpty()){
            throw new RuntimeException("参数为空!");
        }
        // old function has error must be new method by under function
       /* List<RepaymentEntity> repaymentEntities = iRepaymentMapper.selectLoanByAmountCertNo(loan);
        List<ActiveRepayOperate> activeRepayOperates = iRepaymentMapper.selectByCertNoActive(loan);
        if(!repaymentEntities.isEmpty()){
            for (ActiveRepayOperate activeRepayOperate : activeRepayOperates) {
                RepaymentMergeActive mergeActive = new RepaymentMergeActive();
                mergeActive.setCertNo(repaymentEntities.getFirst().getCertNo());
                mergeActive.setLoanNo(activeRepayOperate.getLoanNo());
                //mergeActive.setPaymentType(repaymentEntity.getPaymentType());
                mergeActive.setBankNo(activeRepayOperate.getBankNo());
                mergeActive.setResult(Integer.parseInt(activeRepayOperate.getContractStatus()));
                mergeActive.setUpdateTime(activeRepayOperate.getFinishTime());
                mergeActive.setLoanAmount(activeRepayOperate.getLoanAmount());
                mergeActive.setSuccessAmount(activeRepayOperate.getSuccessAmount());
                resultList.add(mergeActive);
            }
           // return resultList;
        }*/
        List<NplmRepayPlan> newPlanList =  nplmRepayPlanMapper.selectPlanListByLoan(loan);
        NplmLoanContract contract = nplmLoanContractMapper.selectLoanNoObjectByCertNo(loan);
        if(!newPlanList.isEmpty()){
            for (NplmRepayPlan nplmRepayPlan : newPlanList) {
                RepaymentMergeActive repaymentMergeActive = new RepaymentMergeActive();
                //repaymentMergeActive.setCertNo(nplmOvrdueCase.getCertNo());
                repaymentMergeActive.setLoanNo(nplmRepayPlan.getLoanNo());
                repaymentMergeActive.setLoanAmount(contract.getLoanAmount());
                repaymentMergeActive.setResult(Integer.parseInt(nplmRepayPlan.getStatus()));
                repaymentMergeActive.setSuccessAmount(nplmRepayPlan.getIndeedTotal());
                if (null != nplmRepayPlan.getRepayDate()){
                    repaymentMergeActive.setUpdateTime(nplmRepayPlan.getRepayDate());
                }else {
                    repaymentMergeActive.setUpdateTime(null);
                }
                resultList.add(repaymentMergeActive);
            }
          //  return resultList;
        }

        return resultList;
    }

    @Override
    public List<Map<String, Object>> selectInfoByLoanNo(String mobile) {
        //first select userinfo table get certNo
        //mobile = "15081461401";
        List<Map<String, Object>> maps = Lists.newArrayList();
        List<Map<String,Object>> result = Lists.newArrayList();
        List<Map> strings = nplmLoanContractMapper.selectLoanNobyMobile(mobile);
        List<UserInfoSso> userInfoSso = null;
        if(strings.isEmpty()){
            userInfoSso = userInfoSsoMapper.selectIsExistCertNo(mobile);
        }
        String certNo = "";
        Set<String> tempSet = null;
        List<NplmOvrdueCase> nplmOvrdueCases = null;
        if(!strings.isEmpty()){
            List<String> tempLoanNo = Lists.newArrayList();
            certNo = String.valueOf(strings.getFirst().get("CERT_NO"));
            for (Map string : strings) {
                tempLoanNo.add(string.get("LOAN_NO").toString());
            }
            tempSet = new HashSet<>(tempLoanNo);
        }else{
            List<String> tempLoanNo = Lists.newArrayList();
            certNo = userInfoSso.getFirst().getCertNo();
            if(null != certNo && !certNo.isEmpty()) {
                nplmOvrdueCases = nplmOverdueCaseMapper.selectByCertNo(certNo);
            }
            assert nplmOvrdueCases != null;
            if(!nplmOvrdueCases.isEmpty()){
                for (NplmOvrdueCase nplmOvrdueCase : nplmOvrdueCases) {
                    tempLoanNo.add(nplmOvrdueCase.getLoanNo());
                }
            }
            tempSet = new HashSet<>(tempLoanNo);
        }
      /*  if(!certNo.isBlank()){
            tempSet.addAll(billMapper.selectLoanNoByCertNo(certNo));
        }*/
        List<String> billEntity = new ArrayList<>(tempSet);
        if(!billEntity.isEmpty()){
            for (String entity : billEntity) {
                if (!entity.isBlank()) {
                    //use not blank loanNo select bill info and
                    log.info("entity value is {}",entity);
                    maps.addAll(iLoanContractMapper.selectLoanInfoByLoanNo(entity));
                }
            }
        }
        if(!maps.isEmpty()){
            int numCount = 0;
            int sumAmount = 0;
            StringBuilder loanNo = new StringBuilder();
            for (Map<String, Object> stringObjectMap : maps) {
                numCount += Integer.parseInt(stringObjectMap.get("NUMCOUNT").toString());
                sumAmount += Integer.parseInt(stringObjectMap.get("SUMAMOUNT").toString());
                loanNo.append(stringObjectMap.get("LOANNO").toString()).append(",");
            }
            log.info("numCount value is {},sumAmount value is {}",numCount,sumAmount);
            Map<String,Object> map = Maps.newHashMap();
            map.put("numCount",numCount);
            map.put("sumAmount",sumAmount);
            map.put("loanNo", loanNo);
            result.add(map);
        }
        if(maps.isEmpty()) {
            AjaxResult a = selectInfoByLoanNoNplm(mobile);
            Map<String, Object> stringObjectMap = new HashMap<>();
            if (a.isSuccess()) {
                List<NplmLoanContract> nplmLoanContracts = (List<NplmLoanContract>) a.get("data");
                if (!nplmLoanContracts.isEmpty()) {
                    stringObjectMap.put("numCount", nplmLoanContracts.size());
                    stringObjectMap.put("sumAmount", nplmLoanContracts.stream()
                            .map(NplmLoanContract::getLoanAmount)
                            .reduce(BigDecimal.ZERO, BigDecimal::add));
                    result.add(stringObjectMap);
                    return result;
                }
            }
        }
        log.info("result value is {}",result);
        return result;
    }

    @Override
    public AjaxResult selectInfoByLoanNoNplm(String certNo) {
        UserInfoSso userInfoSso = userInfoSsoMapper.selectByCertNoDefault(certNo);
        if (userInfoSso == null){
            return AjaxResult.error("用户信息不存在");
        }
        if (userInfoSso.getCustNo() != null){
            List<NplmLoanContract> nplmLoanContracts = nplmLoanContractMapper.selectByCertNo(userInfoSso.getCustNo());
            return AjaxResult.success(nplmLoanContracts);
        }
        return AjaxResult.error("系统错误");
    }
}
